/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup AudioDecoder
 * @{
 *
 * @brief AudioDecoder模块提供用于音频解码功能的函数。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 *
 * @since 9
 * @version 1.0
 */

/**
 * @file native_avcodec_audiodecoder.h
 *
 * @brief 声明用于音频解码的Native API。
 *
 * @since 9
 * @version 1.0
 */

#ifndef NATIVE_AVCODEC_AUDIODECODER_H
#define NATIVE_AVCODEC_AUDIODECODER_H

#include <stdint.h>
#include <stdio.h>
#include "native_averrors.h"
#include "native_avformat.h"
#include "native_avmemory.h"
#include "native_avcodec_base.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 通过mime类型创建一个音频解码器实例，大多数情况下推荐使用该接口。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param mime mime类型描述字符串，参考{@link OH_AVCODEC_MIMETYPE_AUDIO_AAC}
 * @return 返回一个指向OH_AVCodec实例的指针
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_AudioDecoder_CreateByMime(const char *mime);

/**
 * @brief 通过音频解码器名称创建一个音频解码器实例，使用这个接口的前提是必须清楚解码器准确的名称。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param name 音频解码器名称
 * @return 返回一个指向OH_AVCodec实例的指针
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_AudioDecoder_CreateByName(const char *name);

/**
 * @brief 清空解码器内部资源，并销毁解码器实例
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Destroy(OH_AVCodec *codec);

/**
 * @brief 设置异步回调函数，使得你的应用能够响应音频解码器产生的事件，该接口被调用必须是在Prepare被调用前。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param callback 一个包含所有回调函数的集合体，参考{@link OH_AVCodecAsyncCallback}
 * @param userData 用户特定数据
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData);

/**
 * @brief 配置音频解码器，典型地，需要配置被解码音频轨道的描述信息，这些信息能够从容器中提取出来，
 * 该接口被调用必须是在Prepare被调用前。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param format 指向OH_AVFormat的指针，用以给出待解码音频轨道的描述信息
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Configure(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief 准备解码器内部资源，调用该接口前必须先调用Configure接口。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Prepare(OH_AVCodec *codec);

/**
 * @brief 启动解码器，该接口必须在已经Prepare成功后调用。
 * 在启动成功后，解码器将开始报告{@link OH_AVCodecOnNeedInputData}事件。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Start(OH_AVCodec *codec);

/**
 * @brief 停止解码器。在停止后可通过Start重新进入Started状态，但需要注意的是，若先前给解码器输入过
 * Codec-Specific-Data，则需要重新输入。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Stop(OH_AVCodec *codec);

/**
 * @brief 清空解码器内部缓存的输入输出数据。在该接口被调用后，所有先前通过异步回调报告的Buffer的索引都将
 * 失效，确保不要再访问这些索引对应的Buffers。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_Flush(OH_AVCodec *codec);

/**
 * @brief 重置解码器。如需继续解码工作，需要重新调用Configure接口以配置该解码器实例。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */

OH_AVErrCode OH_AudioDecoder_Reset(OH_AVCodec *codec);

/**
 * @brief 获取该解码器输出数据的描述信息，需要注意的是，返回值所指向的OH_AVFormat实例需调用者手动释放。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 返回OH_AVFormat句柄指针，需调用者手动释放;
 * @since 9
 * @version 1.0
 */
OH_AVFormat *OH_AudioDecoder_GetOutputDescription(OH_AVCodec *codec);

/**
 * @brief 向解码器设置动态参数，注意：该接口仅能在解码器被启动后调用，同时错误的参数设置，可能会导致解码失败。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param format OH_AVFormat句柄指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief 将填充好数据的输入Buffer提交给音频解码器。{@link OH_AVCodecOnNeedInputData}回调会报告可用的输入
 * Buffer及对应的索引值。一旦指定索引的Buffer被提交给解码器，直到再一次收到{@link OH_AVCodecOnNeedInputData}
 * 回调报告相同索引的Buffer可用前，该Buffer都不可以再次被访问。另外，对于部分解码器，要求在最开始给解码器输入
 * Codec-Specific-Data，用以初始化解码器的解码过程。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param index 输入Buffer对应的索引值
 * @param attr 描述该Buffer内所包含数据的信息
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr);

/**
 * @brief 将处理结束的输出Buffer交还给解码器。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioDecoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param index 输出Buffer对应的索引值
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioDecoder_FreeOutputData(OH_AVCodec *codec, uint32_t index);

#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVCODEC_AUDIODECODER_H